package org.example.quartz.BIP;

import cn.hutool.core.util.ObjectUtil;
import cn.hutool.db.Session;
import cn.hutool.extra.spring.SpringUtil;
import cn.hutool.http.HttpRequest;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import lombok.extern.slf4j.Slf4j;
import org.example.quartz.service.LogService;
import org.example.quartz.service.OrgService;
import org.example.quartz.service.UtilService;
import org.example.quartz.task.QuartzTaskJob;
import org.example.quartz.util.DataSourceUtil;
import org.quartz.DisallowConcurrentExecution;
import org.quartz.JobExecutionContext;
import org.quartz.PersistJobDataAfterExecution;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.stereotype.Component;

import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

@Slf4j
@Component
// 再Job被执行结束后，将会更新JobDataMap，这样下次Job执行后悔使用新的值而不是初始值
@PersistJobDataAfterExecution
// 同一时间将只有一个Job实例被执行，为了避免并发问题导致数据紊乱，建议这两个注解一起使用
@DisallowConcurrentExecution
public class ReturnGLQuartz_BIP implements QuartzTaskJob {

    Map<String, Object> gsMap = DataSourceUtil.getGS();
    //全局接口配置
    String IP = (String) gsMap.get("IP");
    String PORT = (String) gsMap.get("PORT");
    String ECC = (String) gsMap.get("ECC");
    String Bearer = (String) gsMap.get("Bearer");

    //日志
    LogService loginfo = SpringUtil.getBean(LogService.class);
    //orgService
    OrgService orgService = SpringUtil.getBean(OrgService.class);
    //orgService
    UtilService utilService = SpringUtil.getBean(UtilService.class);


    /**
     * 凭证回写接口
     * 接口地址：GSCloud文档3.14
     * http://ip:port/api/jg/fiaccbddata/v1.0/fiaccbdinterface/getPzInfoResult
     **/
    @Override
    public void execute(JobExecutionContext context) {
        try {
            Session DMSession = DataSourceUtil.getMysqlSession();
            //传入变量 lastTime 最后抓取时间
            //链接BIP数据库，查询出需要同步的数据，根据TS时间进行判断。
            //TS从中间库表获取到最后一次更新时间，根据此时间进行增量查询推送；
            //中间库日志表记录推送日志，成功、失败、返回信息等（备查）
            //中间库记录最后推送数据的时间，根据时间进行下次查询的条件；
            //查询脚本
            /**
             *凭证中间库已推送数据，未收到凭证回写数据的数据。需要定时调用GS查询接口，进行查询回写
             * 回写的同时，需要将id同时回写给之前的数据，以及id同此数据相同的凭证数据（修改、删除类）
             *{
             *   "ORGCODE": "A0001",
             *   "YEAR": "2024",
             *   "LYPZIDS": "f271090c-7e36-4ddd-9e10-3a12fb24e8a6,e271090c-7e36-4ddd-9e10-3a12fb24e8a6"
             * }
             * */
            //查询出需要回传信息的id串   账簿code及查询年份信息
            //查询脚本
            String methodName = "ReturnGLQuartz";
            JdbcTemplate jdbcTemplate = SpringUtil.getBean(JdbcTemplate.class);
            //时间格式化
            DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
            //1、查询IDS,需要查询的凭证id  V_RETURNVOUCHERID
            String selectSQL = "SELECT YEAR,ORGCODE,BATCHNO,LYPZID FROM " + utilService.getGSYY() + ".V_RETURNVOUCHERID";
            //查询数据，根据数据结果推送给GS浪潮
            List<Map<String, Object>> maps = jdbcTemplate.queryForList(selectSQL);
            if (maps.size() > 0) {
                //根据年度和账簿分组
                Map<String, List<Map<String, Object>>> returnList = maps.stream().collect(Collectors.groupingBy(i -> i.get("YEAR") + "," + i.get("ORGCODE")));
                for (Map.Entry<String, List<Map<String, Object>>> returnOBJ : returnList.entrySet()) {
                    //拼接需要查询的id串
                    String voucherIDS = "";
                    String ORGCODE = "";
                    String YEAR = "";
                    List<Map<String, Object>> value = returnOBJ.getValue();
                    for (Map<String, Object> returnid : value) {
                        voucherIDS += returnid.get("LYPZID") + ",";
                        ORGCODE = orgService.selectGsztCodeByYYZTCODE((String) returnid.get("ORGCODE"), jdbcTemplate);
                        YEAR = (String) returnid.get("YEAR");
                    }

                    //去掉结尾的,
                    voucherIDS = voucherIDS.substring(0, voucherIDS.lastIndexOf(','));
                    String GsJson = "{\n" +
                            "    \"ORGCODE\": \"" + ORGCODE + "\",\n" +
                            "    \"YEAR\": \"" + YEAR + "\",\n" +
                            "    \"LYPZIDS\": \"" + voucherIDS + "\"\n" +
                            "}";
                    GsJson = GsJson.replace("null", "");
                    //调用GS接口，推送给GS浪潮，获取返回值;
                    //1、推送用户档案
                    String gsUrl = IP + ":" + PORT + "/api/jg/gl/v1.0/fiaccinterface/getPzInfoResult";
                    String returnMSG = HttpRequest.post(gsUrl)
                            .header("Content-Type", "application/json")
                            .header("Accept-Language", "zh-CHS")
                            .header("X-ECC-Current-Tenant", ECC)
                            .header("Authorization", Bearer).timeout(200000)
                            .body(GsJson).execute().body();
                    String msg = "";
                    if (!returnMSG.isEmpty()) {
                        JSONArray returnidLIST = JSONArray.parseArray(returnMSG);
                        String updateGSID = "";
                        for (int y = 0; y < returnidLIST.size(); y++) {
                            JSONObject returnObj = returnidLIST.getJSONObject(y);
                            /**
                             * {
                             * "code": "0",//0操作成功，1操作失败，2操作未执行
                             * "msg": "",//失败时返回失败原因
                             * "ORGCODE": "A0001",
                             * "YEAR": "2024",
                             * "LYPZID": "f271090c-7e36-4ddd-9e10-3a12fb24e8a6" ,
                             * “ACCDOCCODE”:”记000004”,
                             * "PZID": "334b1a0a-19a2-6104-cc16-486601ca6e4b"//浪潮凭证id
                             * },
                             * */
                            String LYPZID = (String) returnObj.get("lypzid");
                            String PZID = (String) returnObj.get("pzid");
                            if (!ObjectUtil.isEmpty(returnObj.get("msg"))) {
                                if (returnObj.get("msg").toString().contains("未执行")) {
                                    continue;
                                }
                                msg = returnObj.get("msg").toString().replace("'", "").replace("；", "").replace("，", "").replace("：", "").replace("。", "");
                            } else {
                                msg = "";
                            }
                            if (msg.length() > 500) {
                                msg = msg.substring(0, 500).replace("'", "").toString();
                            }
                            String GSPZCODE = (String) returnObj.get("accdoccode");
                            //成功
                            if (returnObj.get("code").toString().equals("0")) {
                                //修改gsid
                                updateGSID += "update " + utilService.getGSYY() + ".gl_detail set REFERENCEID = '" + PZID + "',RETURNMSG = '" + msg + "',GSSTATUS = '1',GSPZCODE = '" + GSPZCODE + "' where LYPZID = '" + LYPZID + "';";

                                //失败
                            } else if (returnObj.get("code").toString().equals("1")) {
                                updateGSID += "update " + utilService.getGSYY() + ".gl_detail set REFERENCEID = '" + PZID + "',RETURNMSG = '" + msg + "',GSSTATUS = '2',GSPZCODE = '" + GSPZCODE + "' where LYPZID = '" + LYPZID + "';";

                            } else if (returnObj.get("code") == null && ("").equals(returnObj.get("code"))) {
                                //写入日志表
                                int loginsert = loginfo.loginfo(jdbcTemplate, methodName, LocalDateTime.now().toString(), "数据返回异常", GsJson, returnMSG, "", "", gsUrl, formatter.format(LocalDateTime.now()));
                                if (loginsert > 0) {
                                    //System.out.println("日志写入成功！！");
                                } else {
                                    System.out.println("日志写入失败！！");
                                }
                            }else {
                                //写入日志表
                                int loginsert = loginfo.loginfo(jdbcTemplate, methodName, LocalDateTime.now().toString(), "数据返回异常", GsJson, returnMSG, "","", gsUrl, formatter.format(LocalDateTime.now()));
                                if (loginsert > 0) {
                                    //System.out.println("日志写入成功！！");
                                } else {
                                    System.out.println("日志写入失败！！");
                                }
                            }
                        }
                        int updateV = 0;
                        if (!updateGSID.isEmpty()) {
                            String updateSql="BEGIN " + "\n";
                            updateSql+= updateGSID;
                            updateSql += " END;" + "\n";
                            updateV = jdbcTemplate.update(updateSql);
                            //updateV = jdbcTemplate.update(updateGSID);
                        }
                        //System.out.println("执行SQL修改方法");
                        if (updateV > 0) {
                            // msg += "-------凭证ID"+PZID+"=====yyid:"+LYPZID+"回写成功；";
                            System.out.println("执行SQL修改方法---成功");
                        } else {
                            // msg += "-------凭证ID"+PZID+"=====yyid:"+LYPZID+"回写失败；";
                            System.out.println("执行SQL修改方法---失败");
                        }
                        int loginsert = loginfo.loginfo(jdbcTemplate, methodName, LocalDateTime.now().toString(), "查询成功", GsJson, returnMSG, "", "YYID", gsUrl, formatter.format(LocalDateTime.now()));
                        if (loginsert > 0) {
                            //System.out.println("日志写入成功！！");
                        } else {
                            System.out.println("日志写入失败！！");
                        }
                    }
                }

            } else {
                System.out.println(methodName + ":暂无新数据推送");
            }
        } catch (Exception e) {
            throw new RuntimeException(e);
        } finally {
            //关闭链接
            DataSourceUtil.closeOracleSession();
            DataSourceUtil.closeMysqlSession();
        }
    }
}

